package com.yq.ylmall.search.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.yq.ylmall.client.product.ProductFeignClient;
import com.yq.ylmall.constant.EsConstant;
import com.yq.ylmall.dto.search.QueryPageDto;
import com.yq.ylmall.search.document.ProductDocument;
import com.yq.ylmall.search.repository.ProductRepository;
import com.yq.ylmall.search.service.IProductService;
import com.yq.ylmall.vo.product.ProductDetailsVo;
import com.yq.ylmall.vo.product.ProductInfoVo;
import com.yq.ylmall.vo.product.ProductSkuVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.ScriptSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class ProductServiceImpl implements IProductService {

    private final ProductRepository productRepository;
    private final ProductFeignClient productFeignClient;
    private final ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public List<SearchHit<ProductDocument>> getIndexBySort() {
        // 初始化查询
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        // 构建排序条件
        queryBuilder.withSort(SortBuilders.fieldSort("sort").order(SortOrder.DESC));
        queryBuilder.withSort(SortBuilders.scriptSort(new Script("Math.random()"), ScriptSortBuilder.ScriptSortType.NUMBER));

        // 构建分页条件
        queryBuilder.withPageable(PageRequest.of(0, 20));
        // 执行查询
        SearchHits<ProductDocument> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), ProductDocument.class);
        return searchHits.getSearchHits();
    }

    @Override
    public List<SearchHit<ProductDocument>> query(QueryPageDto dto) {
        // 初始化查询
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        // 构建查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
                .should(QueryBuilders.multiMatchQuery(dto.getKeyword(), "productName", "productDesc"));
        queryBuilder.withQuery(boolQuery);
        if (dto.getStartPrice() != null && dto.getEndPrice() != null) {
            // 根据销售价格区间查询
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("salePrice")
                    .from(dto.getStartPrice()).to(dto.getEndPrice());
            queryBuilder.withQuery(rangeQuery);
        }

        // 构建排序条件
        queryBuilder.withSort(SortBuilders.fieldSort("sort").order(SortOrder.DESC));
        queryBuilder.withSort(SortBuilders.fieldSort("saleNum").order(dto.getSaleNum() ? SortOrder.DESC : SortOrder.ASC));
        queryBuilder.withSort(SortBuilders.fieldSort("commentCount").order(dto.getCommentCount() ? SortOrder.DESC : SortOrder.ASC));

        // 构建高亮查询
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags(EsConstant.HIGH_LIGHT_START_TAG);
        highlightBuilder.postTags(EsConstant.HIGH_LIGHT_END_TAG);
        highlightBuilder.field("productName").field("productDesc");
        queryBuilder.withHighlightBuilder(highlightBuilder);

        // 构建分页条件
        queryBuilder.withPageable(PageRequest.of(dto.getPageNum() - 1, dto.getPageSize()));

        // 执行查询
        SearchHits<ProductDocument> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), ProductDocument.class);
        return searchHits.getSearchHits();
    }

    @Override
    public List<String> queryKeyword(String q) {
        // 初始化查询
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

        // 构建查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
                .should(QueryBuilders.multiMatchQuery(q, "productName", "brandName"));
        queryBuilder.withQuery(boolQuery);

        // 构建排序条件
        queryBuilder.withSort(SortBuilders.fieldSort("sort").order(SortOrder.DESC));

        // 构建高亮查询
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags(EsConstant.HIGH_LIGHT_START_TAG);
        highlightBuilder.postTags(EsConstant.HIGH_LIGHT_END_TAG);
        highlightBuilder.field("productName").field("brandName");
        queryBuilder.withHighlightBuilder(highlightBuilder);

        // 构建分页条件，只取10条
        queryBuilder.withPageable(PageRequest.of(0, 10));

        // 执行查询
        SearchHits<ProductDocument> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(), ProductDocument.class);

        // 处理结果，留下高亮字段
        TreeSet<String> resultSet = new TreeSet<>();  // 去重、排序
        searchHits.getSearchHits().forEach(hit -> {
            Collection<List<String>> values = hit.getHighlightFields().values();
            values.forEach(resultSet::addAll);
        });
        return new ArrayList<>(resultSet);
    }

    @Override
    public void upperProduct(Long id) {
        ProductInfoVo vo = productFeignClient.getById(id);
        if (ObjectUtil.isEmpty(vo)) {
            log.warn("商品上架失败，调用商品服务结果：{}", vo);
            return;
        }
        ProductDocument doc = new ProductDocument();
        doc.setId(vo.getId());
        doc.setProductName(vo.getProductName());
        doc.setSort(vo.getSort());
        doc.setBrandId(vo.getBrandId());
        doc.setBrandName(vo.getBrandName());
        doc.setCommentCount(0);
        // 商品描述
        ProductDetailsVo productDetails = vo.getProductDetails();
        doc.setProductDesc(productDetails.getProductDesc());
        doc.setImageUrls(productDetails.getImageUrls());
        doc.setSliderUrls(productDetails.getSliderUrls());
        // 商品sku
        List<ProductSkuVo> productSkuList = vo.getProductSkuList();
        if (productSkuList != null && !productSkuList.isEmpty()) {
            ProductSkuVo skuVoOne = productSkuList.get(0);
            doc.setDiscount(0.0);
            doc.setCommentCount(0);
            doc.setSalePrice(skuVoOne.getSalePrice());
            doc.setSaleNum(skuVoOne.getSaleNum());
            doc.setMarketPrice(skuVoOne.getMarketPrice());
            // 遍历所有Sku，统计库存
            Integer stockTotal = productSkuList.stream()
                    .map(ProductSkuVo::getStockNum)
                    .reduce(Integer::sum).get();
            doc.setStockNum(stockTotal);
            doc.setHasStock(stockTotal > 0);
            // 遍历所有Sku，设置 skuList
            List<ProductDocument.ProductSkuDocument> skuDocs = productSkuList.stream().map(sku -> {
                ProductDocument.ProductSkuDocument skuDoc = BeanUtil.copyProperties(sku, ProductDocument.ProductSkuDocument.class);
                skuDoc.setSkuId(sku.getId());
                skuDoc.setHasStock(sku.getStockNum() > 0);
                return skuDoc;
            }).collect(Collectors.toList());
            doc.setSkuList(skuDocs);
        }
        productRepository.save(doc);
        log.info("商品成功上架");
    }

    @Override
    public void lowerProduct(Long id) {
        productRepository.deleteById(id);
        log.info("商品成功下架");
    }

}
